<?php

use \GatewayWorker\Lib\Gateway;  

require_once dirname(__DIR__) . '/public.class.model.php';
class Room_Model extends Public_Model
{
	
	/***************************
			common_function	
	***************************/
	
	
	/*
		断线
	*/
	public function userDisconnected($arrData)
	{
		$timestamp = time();

		if(!isset($arrData['gaming_roomid']) || trim($arrData['gaming_roomid']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		if(!isset($arrData['account_id']) || trim($arrData['account_id']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		
		$REMOTE_ADDR = "unknow";
		if(isset($arrData['REMOTE_ADDR']))
		{
			$REMOTE_ADDR = $arrData['REMOTE_ADDR'];
		}
		
		$room_id 		= $arrData['gaming_roomid'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
		$clients_of_groupid = array_keys($clients_of_groupid);
		
		if($this->queryOnlineStatus($room_id, $account_id)){
			$this->writeLog("[$room_id] [$account_id] is still in room");
			return true;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		if($this->queryTicketChecked($room_id, $account_id) == 0) 
		{
			$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
			$zrem_result = $Redis_Model->zremSet($RoomSequence_Key,array($account_id));

			$account_status = Game::AccountStatus_Initial;
		}
		else
		{
			$account_status = $this->queryAccountStatus($room_id, $account_id);
			if($account_status == Game::AccountStatus_Ready){	//准备状态下断线， 变为未准备
				
				$account_status = Game::AccountStatus_Notready;
			}
		}
		$this->updateAccountStatus($room_id, $account_id, $account_status);
		$this->writeLog("[$room_id] ($account_id) 离线   REMOTE_ADDR:".$REMOTE_ADDR);
		
		//获取房间状态
		$room_status = $this->queryRoomStatus($room_id);
		if($room_status === Redis_CONST::DATA_NONEXISTENT || $room_status == Game::RoomStatus_Closed ){	//房间已经废弃或未激活
			return true;
		}

		if($room_status == Game::RoomStatus_Waiting)
		{
			$ready_count = $this->queryReadyCount($room_id);
			if($ready_count < 2){
				//取消倒计时
				$this->deleteRoomTimer($room_id);
				$arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
				$this->pushMessageToGroup($room_id, $arr);
			} else {
				$this->startGame($room_id);
			}
		}

		$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
		//判断是否全部人离线
		if(count($clients_of_groupid) == 0)
		{
			$this->setupClearRoomPassiveTimer($room_id);
		}

		return true; 
	}
	
	
	
	/***************************
			logic_function	
	***************************/
	
	/*
		创建房间
	*/
	public function createRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['data_key']) || trim($data['data_key']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(createRoom):lack of data_key"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"data_key");
		}
        //获取随机房间号
        $newRoomNumber = $this->getNewRoomNumber();
		$data_key = $data['data_key'];
		$spend_ticket_count = Game::Default_SpendTicketCount;	//默认消耗房卡
		$base_score = Game::Default_Score;						//默认底注
		$rule_type = 1;											//默认分数规则
		$banker_mode = Game::BankerMode_SeenGrab;	//默认明牌抢庄  //BankerMode_FreeGrab  BankerMode_NoBanker

		$carddi_multiple = 1;		//地公
		$cardlei_multiple = 1;		//雷公
		$cardtian_multiple = 1;		//天公
		$cardbao9_multiple = 1;		//暴玖


		//获取维护公告
		$alert_type = -1;
		$alert_text = "";
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
			$result['alert_type'] = $alert_type;
			return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>$alert_text); 
		}

		//筹码类型
		if(isset($data['bet_type']) && in_array($data['bet_type'], [1,2,3]))
		{
			$bet_type = $data['bet_type'];
		} else {
			$this->logMessage('error', "function(createRoom):用户".$account_id." bet_type error：".__FILE__.__LINE__);
			return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>"房卡规则错误"); 
		}

		//房间人数类型
		if(!isset($data['max_count_type']) || !in_array($data['max_count_type'], [1,2]))
		{
			$this->logMessage('error', "function(createRoom):lack of max_count_type"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"max_count_type");
		}
		//消耗房卡类型
		if(!isset($data['ticket_type']) || !in_array($data['ticket_type'], [1,2]))
		{
			$this->logMessage('error', "function(createRoom):用户".$account_id." ticket_type error："." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"ticket_type");
		}
        if(!isset($data['client_name'])){
            $data['client_name'] = "wechat";
        }
        if(!isset($data['client_type'])){
            $data['client_type'] = "wechat";
        }
        if(!isset($data['daikai_id'])){
            $data['daikai_id'] = 0;
        }

		//人数类型 1九人 2十二人
		$max_count_type = $data['max_count_type'];
		if($max_count_type==1){
			$room_max_count = 9;
			$spend_ticket_count = Config::Rule_TicketType_Nine * $data['ticket_type'];
		} else {
			$room_max_count = 12;
			$spend_ticket_count = Config::Rule_TicketType_Twelve * $data['ticket_type'];
		}
		//每轮局数
		$total_num = Config::GameNumber_Each * $data['ticket_type'];
		
		//分数规则
			$rule_type = 1;
			$card7_multiple = Game::Rule_Card7_Multiple_1;
			$card8_multiple = Game::Rule_Card8_Multiple_1;
			$card9_multiple = Game::Rule_Card9_Multiple_1;
			$card10_multiple = Game::Rule_Card10_Multiple_1;
		
		//特殊牌型
		if(isset($data['is_cardjoker']) && $data['is_cardjoker'] == 1)
		{
			$carddi_multiple = Game::Rule_CardDi_Multiple;
			$cardlei_multiple = Game::Rule_CardLei_Multiple;
			$cardtian_multiple = Game::Rule_CardTian_Multiple;
		}
		if(isset($data['is_cardbao9']) && $data['is_cardbao9'] == 1)
		{
			$cardbao9_multiple = Game::Rule_CardBao9_Multiple;
		}
		$pay_type = Config::Ticket_Mode;

		$MMYSQL = $this->initMysql();
		//判断房卡余额
		$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();
		if($my_ticket_count >= $spend_ticket_count){

		} else {
			$this->writeLog("($account_id) 牌券不足");
			$result['alert_type'] = 1;	//1房卡不足
			return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房卡不足"); 
		}

		//判断房间申请记录是否存在
		$room_where = 'data_key="'.$data_key.'"';
		$room_sql = 'select room_id,room_number,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$room_aid = $account_id;
			$is_close = G_CONST::IS_FALSE;
			
			$r_array['create_time'] = $timestamp;
			$r_array['create_appid'] = "aid_".$account_id;
			$r_array['update_time'] = $timestamp;
			$r_array['update_appid'] = "aid_".$account_id;
			$r_array['is_delete'] = G_CONST::IS_FALSE;
			$r_array['data_key'] = $data_key;
			$r_array['account_id'] = $room_aid;
			$r_array['is_close'] = G_CONST::IS_FALSE;
			$r_array['max_count'] = $room_max_count;
            $r_array['game_type'] = Game::Game_Type;
			$r_array['new_room_number'] = $newRoomNumber;
            $r_array['client_name'] = $data['client_name'];
            $r_array['client_type'] = $data['client_type'];
			$r_array['daikai_id'] = $data['daikai_id'];
 			$room_id = $MMYSQL->insertReturnID(Room,$r_array);
			if($room_id > 0)
			{
				$room_number = 100000 + $room_id * 10 + mt_rand(1,9);
			}
			else
			{
				$this->logMessage('error', "function(createRoom):用户".$account_id." 创建房间失败："." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>"创建房间失败"); 
			}

			$num_updateSql = 'update '.Room.' set room_number="'.$room_number.'" where room_id='.$room_id;
			$num_updateQuery = $MMYSQL->query($num_updateSql);
		}
		else
		{
			$room_id = $room_query[0]['room_id'];
			$room_number = $room_query[0]['room_number'];
			$room_aid = $room_query[0]['account_id'];
			$is_close = $room_query[0]['is_close'];
		}
		

		//添加房间信息到redis
		$Redis_Model = Redis_Model::getModelObject();
		
		$replyArr = array("[roomid]"=>$room_id);
		$Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
		
		$r_mkv[Redis_Const::Room_Field_Number] = $room_number;	//房间号
		$r_mkv[Redis_Const::Room_Field_GameRound] = 1;			//游戏轮数
		$r_mkv[Redis_Const::Room_Field_GameNum] = 0;			//游戏局数
		$r_mkv[Redis_Const::Room_Field_MaxCount] = $room_max_count;			//游戏人数
		$r_mkv[Redis_Const::Room_Field_Status] = Game::RoomStatus_Waiting;				//房间状态，1等待、2进行中、3关闭
		$r_mkv[Redis_Const::Room_Field_DefaultScore] = $base_score;		//开局默认分数
		$r_mkv[Redis_Const::Room_Field_ActiveUser] = -1;		//当前操作用户
		$r_mkv[Redis_Const::Room_Field_ActiveTimer] = -1;		//当前生效timer
		$r_mkv[Redis_Const::Room_Field_BaseScore] = $base_score;		//当前生效timer
		$r_mkv[Redis_Const::Room_Field_TotalNum] = $total_num;		//每轮总局数
		$r_mkv[Redis_Const::Room_Field_TicketCount] = $spend_ticket_count;		//每轮消耗房卡数量
		$r_mkv[Redis_Const::Room_Field_Creator] = $account_id;		//创建用户
		$r_mkv[Redis_Const::Room_Field_Scoreboard] = "";		//积分榜
		$r_mkv[Redis_Const::Room_Field_Paytype] = $pay_type;		///AA,2房主扣卡

		$r_mkv[Redis_Const::Room_Field_ReadyTime] = -1;		//房间倒计时

		$r_mkv[Redis_Const::Room_Field_StartTime] = -1;		//开局时间

		$r_mkv[Redis_Const::Room_Field_BetType] = $bet_type;		//筹码类型
		$r_mkv[Redis_Const::Room_Field_RuleType] = $rule_type;		//规则类型
		$r_mkv[Redis_Const::Room_Field_Card7] = $card7_multiple;		//7点倍率
		$r_mkv[Redis_Const::Room_Field_Card8] = $card8_multiple;		//8点倍率
		$r_mkv[Redis_Const::Room_Field_Card9] = $card9_multiple;		//9点倍率
		$r_mkv[Redis_Const::Room_Field_Card10] = $card10_multiple;		//0点倍率

		$r_mkv[Redis_Const::Room_Field_CardDi] = $carddi_multiple;			//地公倍率
		$r_mkv[Redis_Const::Room_Field_CardLei] = $cardlei_multiple;		//雷公倍率
		$r_mkv[Redis_Const::Room_Field_CardBao9] = $cardbao9_multiple;		//暴玖倍率
		$r_mkv[Redis_Const::Room_Field_CardTian] = $cardtian_multiple;		//天公倍率

		$r_mkv[Redis_Const::Room_Field_BankerMode] = $banker_mode;		//庄家类型

        $r_mkv[Redis_CONST::Room_Field_NewNumber] = $newRoomNumber;
        $mset_result = $Redis_Model->hmsetField($Room_Key,$r_mkv);
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        $RedisLog_Model->hmsetField(Redis_CONST::Room_New_Key,[$newRoomNumber=>json_encode(["room_number"=>$room_number,"game_type"=>Game::Game_Type, "create_time"=>date('Y-m-d H:i:s',$timestamp),"client_name"=>$data['client_name']])]);

		if(Game::PaymentType_Creator == $pay_type)
		{
			$this->writeLog("[$room_id] ($account_id) 消耗房卡:".$spend_ticket_count);
			//扣除房卡
			$this->balanceTicket($room_id, $account_id, $spend_ticket_count);
		}
		$result['new_room_number'] = $newRoomNumber;
		$result['room_id'] = $room_id;
		$result['room_number'] = $room_number;
		$result['is_close'] = $is_close;
		$result['banker_mode'] = $banker_mode;
		$this->writeLog("[$room_id] ($account_id) 创建房间".$room_number);
		return array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$result,"result_message"=>"创建房间");  
	}

	public function getNewRoomNumber(){
        $ti = microtime();
        list($s,$m) = explode(" ", $ti);
        $newRoomNumber = substr($m + substr($s,2), 4);
        if ($newRoomNumber <= 100000) $newRoomNumber += 100000;
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        if ($RedisLog_Model->hexistsField('RoomNumber',$newRoomNumber) == Redis_CONST::Key_Nonexistent){
            return $newRoomNumber;
        }else{
            return $this->getNewRoomNumber();
        }
    }

	

	/*
		进入房间
	*/
	public function joinRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(joinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close,max_count from '.Room.' where '.$room_where;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row)
		{
			$this->logMessage('error', "function(joinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}
		else
		{
			$room_id = $room_row['room_id'];
			$room_max_count = $room_row['max_count'];
			if($room_row['is_close'])
			{
				$result['room_status'] = 4;
				return array("result"=>"0","operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}

		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);


		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
		$RoomScore_Field_User = strtr(Redis_Const::RoomScore_Field_User, $replyArr);
			
		$rsSeq_score = $Redis_Model->getZscore($RoomSequence_Key,$account_id);
		//判断用户是否已加入房间
		if(Redis_CONST::DATA_NONEXISTENT !== $rsSeq_score)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$RoomScore_Field_User);
			//获取用户所在位置
			$serial_num = $rsSeq_score;

			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			$serial_num = $this->joinRoomTransaction($room_id,$account_id, $room_max_count);
			if(!$serial_num){
				$result['alert_type'] = 2;
				return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房间人数已满"); 
			}
			
			//添加默认分数
			$rScore_score = 0;
			$rScore_mkv[$RoomScore_Field_User] = $rScore_score;
			$hmset_result = $Redis_Model->hmsetField($RoomScore_Key,$rScore_mkv);

			//首次进房初始状态
			$account_status =  Game::AccountStatus_Initial;
			$AccountStatus_Key = strtr(Redis_Const::AccountStatus_Key, $replyArr);
			$mkv[$account_id] = $account_status;
			$mset_result = $Redis_Model->hmsetField($AccountStatus_Key,$mkv);

		}

		//绑定用户UID
		$room_aid = strtr(Game::RoomUser_UID, $replyArr);

		Gateway::bindUid($client_id, $room_aid);
		//Gateway::bindUid($client_id, $account_id);
		Gateway::joinGroup($client_id, $room_id);
		
		$room_data = $this->queryRoomData($room_id);
		$game_num = $room_data['gnum'];
		$room_status = $room_data['stat'];
		$room_ary['scoreboard'] = $room_data['scoreboard'];
		if($room_ary['scoreboard'] !== ""){
			$room_ary['scoreboard'] = json_decode($room_ary['scoreboard']);
		} else {
			$room_ary['scoreboard'] = new stdClass();
		}
		$room_ary['total_num'] = $room_data['totalnum'];
		$room_ary['base_score'] = $room_data['baseScore'];
		$banker_mode = $room_data['bankermode'];
		$ready_time = $room_data['readyTime'];
        $room_ary['creator_id'] = $room_data[Redis_CONST::Room_Field_Creator];

		if($room_status == Game::RoomStatus_Waiting && $account_status != Game::AccountStatus_Initial && $account_status != Game::AccountStatus_Notready && $account_status != Game::AccountStatus_Ready)
		{
			//游戏未开始，用户状态不为 未准备/准备 ，状态异常，修复
			$account_status = $this->joinRoomFixAccountStatus($room_id,$account_id);
		}

		//$game_num = $this->queryGameNumber($room_id);
		//$room_status = $this->queryRoomStatus($room_id);
		$room_ary['room_id'] = $room_id;
		$room_ary['room_number'] = $room_number;
		$room_ary['room_status'] = $room_status;
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		$room_ary['online_status'] = 1;
		$room_ary['serial_num'] = $serial_num;
		$room_ary['game_num'] = $game_num;
		//$room_ary['scoreboard'] = $this->queryScoreboard($room_id);
		//$room_ary['total_num'] = $this->queryTotalNum($room_id);
		//$room_ary['base_score'] = $this->queryBaseScore($room_id);


		$room_ary['score_pool'] = $this->queryPoolScore($room_id);



		//获取房间庄家模式
		//$banker_mode = $this->queryBankerMode($room_id);

		$card_info = array();
		$card_type = 0;
		$combo_array = array();
		$combo_point = 0;
		if($account_status==Game::AccountStatus_Choose || $account_status == Game::AccountStatus_Notgrab || $account_status == Game::AccountStatus_Grab || $account_status == Game::AccountStatus_Bet)
		{
			$card_info = $this->queryCardInfo($room_id, $account_id);
			if($banker_mode != Game::BankerMode_SeenGrab)
			{
				$card_info[0] = "-1";
				$card_info[1] = "-1";
			}
			$card_info[2] = "-1";
		}
		else if($account_status==Game::AccountStatus_Show || $account_status == Game::AccountStatus_Notshow){	//已经看过牌的
			$card_info = $this->queryCardInfo($room_id, $account_id);
			$cards_result = $this->caculateCardValue($room_id, $account_id);
			$combo_array = $cards_result['combo_array'];
			$combo_point = $cards_result['combo_point'];
			$card_type = $cards_result['card_type'];
		}
		$room_ary['cards'] = $card_info;
		$room_ary['card_type'] = $card_type;
		$room_ary['combo_array'] = $combo_array;
		$room_ary['combo_point'] = $combo_point;
		$room_ary['can_break'] = 0;


		//是否庄家
		$is_banker = G_CONST::IS_FALSE;
		$banker_id = $this->queryBanker($room_id);
		if($banker_id == $account_id)
		{
			$is_banker = G_CONST::IS_TRUE;
		}
	

		//推送房间信息
		$room_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
		$this->pushMessageToCurrentClient($room_return);
		
		//返回所有玩家状态给进房玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(is_array($allGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
			$this->pushMessageToCurrentClient($currentGamer_return);

			//$this->logMessage('error', "function(joinRoom):currentGamer_return:".json_encode($currentGamer_return). " in file".__FILE__." on Line ".__LINE__);
		}

		
		//推送当前玩家状态给其他玩家
		$currentGamer = $this->getGamerInfo($room_id,$account_id);
		if(is_array($currentGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer,"result_message"=>"某玩家状态");
			$this->pushMessageToGroup($room_id, $currentGamer_return, $client_id);
		}

		//显示房间目前的倒计时
		//$this->showRoomCountdown($room_id);
		$this->pushRoomCountdown($room_id,$ready_time,$game_num);

		//保存用户当前房间,用户ID
		$_SESSION['gaming_roomid'] = $room_id;
		$_SESSION['account_id'] = $account_id;

		$this->writeLog("[$room_id] ($account_id) 进入房间");
		return OPT_CONST::NO_RETURN;
	}

	protected function joinRoomTransaction($room_id,$account_id,$max_count)
	{
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id);
		$key = strtr(Redis_Const::RoomSequence_Key, $replyArr);

		$redisAuth = $Redis_Model->pingRedisAuth();
		if($redisAuth === G_CONST::EMPTY_STRING || !is_object($redisAuth))
		{
			$this->logMessage('error', "function(joinRoomTransaction):redisAuth is empty string"." in file".__FILE__." on Line ".__LINE__);
			return false;
		}

	    $success = false;
	    $options = array(
	        'cas'   => true,    // Initialize with support for CAS operations
	        'watch' => $key,    // Key that needs to be WATCHed to detect changes
	        'retry' => 3,       // Number of retries on aborted transactions, after
	                            // which the client bails out with an exception.
	    );

	    $redisAuth->transaction($options, function ($tx) use ($key,$account_id, $max_count, &$success) {
	    	$result = $tx->zrange($key,0,-1,'withscores');
	    	if(is_array($result)) {
	    		if(count($result) >= $max_count){
	    			$this->writeLog("joinRoom: accountid".$account_id." 人数已满 ".__FILE__.__LINE__);
	    			$success = false;
	    		} else {
	    			for($serial_num=1;$serial_num<=$max_count;$serial_num++){
	    				if(array_search($serial_num,$result) === false){
							$tx->multi();   // With CAS, MULTI *must* be explicitly invoked.
							$zadd_result = $tx->zadd($key,$serial_num,$account_id);
							$success = $serial_num;
	    					break;
	    				}
	    			}
	    		}
	    	} else {
	    		$this->writeLog("joinRoom:zrange result error ".__FILE__.__LINE__);
	    		$success = false;
	    	}
	    });
	    return $success;
	}





	/*
		刷新房间
	*/
	public function pullRoomInfo($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
		{
			$this->logMessage('error', "function(pullRoomInfo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		$room_id = $data['room_id'];
		$MMYSQL = $this->initMysql();
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
		$RoomScore_Field_User = strtr(Redis_Const::RoomScore_Field_User, $replyArr);
			
		$rsSeq_score = $Redis_Model->getZscore($RoomSequence_Key,$account_id);
		//判断用户是否已加入房间
		if(Redis_CONST::DATA_NONEXISTENT !== $rsSeq_score)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$RoomScore_Field_User);
			//获取用户所在位置
			$serial_num = $rsSeq_score;

			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			$this->logMessage('error', "function(pullRoomInfo):account($account_id) not join room"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"用户未加入房间"); 
		}

		//绑定用户UID
		$room_aid = strtr(Game::RoomUser_UID, $replyArr);


		$room_data = $this->queryRoomData($room_id);
		$game_num = $room_data['gnum'];
		$room_status = $room_data['stat'];
		//$room_ary['scoreboard'] = $room_data['scoreboard']
		$room_ary['total_num'] = $room_data['totalnum'];
		$room_ary['base_score'] = $room_data['baseScore'];
		$banker_mode = $room_data['bankermode'];
		$ready_time = $room_data['readyTime'];

		//获取房间当前局数
		//$game_num = $this->queryGameNumber($room_id);
		//$room_status = $this->queryRoomStatus($room_id);
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		//$room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);
		$room_ary['serial_num'] = $serial_num;
		$room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);

		//获取房间庄家模式
		//$banker_mode = $this->queryBankerMode($room_id);
		
		$card_info = array();
		$card_type = 0;
		$combo_array = array();
		$combo_point = 0;
		if($account_status==Game::AccountStatus_Choose || $account_status == Game::AccountStatus_Notgrab || $account_status == Game::AccountStatus_Grab || $account_status == Game::AccountStatus_Bet)
		{
			$card_info = $this->queryCardInfo($room_id, $account_id);
			if($banker_mode != Game::BankerMode_SeenGrab)
			{
				$card_info[0] = "-1";
				$card_info[1] = "-1";
			}
			$card_info[2] = "-1";
		}
		else if($account_status==Game::AccountStatus_Show || $account_status == Game::AccountStatus_Notshow){	//已经看过牌的
			$card_info = $this->queryCardInfo($room_id, $account_id);
			$cards_result = $this->caculateCardValue($room_id, $account_id);
			$combo_array = $cards_result['combo_array'];
			$combo_point = $cards_result['combo_point'];
			$card_type = $cards_result['card_type'];
		}
		$room_ary['cards'] = $card_info;
		$room_ary['card_type'] = $card_type;
		$room_ary['combo_array'] = $combo_array;
		$room_ary['combo_point'] = $combo_point;
		$room_ary['can_break'] = 0;

		//是否庄家
		$is_banker = G_CONST::IS_FALSE;
		$banker_id = $this->queryBanker($room_id);
		if($banker_id == $account_id)
		{
			$is_banker = G_CONST::IS_TRUE;
		}
		

		//$room_ary['base_score'] = $this->queryBaseScore($room_id);
				
		//返回所有玩家状态给进房玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(!is_array($allGamer))
		{
			$this->logMessage('error', "function(pullRoomInfo):roomid($room_id) no player"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间没有其他用户"); 
		}

		$pull_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"拉取房间信息","all_gamer_info"=>$allGamer);
		$this->pushMessageToCurrentClient($pull_return);

		$this->logMessage('error', "function(pullRoomInfo):用户 $account_id 拉取房间 $room_id 信息"." in file".__FILE__." on Line ".__LINE__);
		$this->logMessage('error', "function(pullRoomInfo):pull_return:".json_encode($pull_return). " in file".__FILE__." on Line ".__LINE__);
		
		return OPT_CONST::NO_RETURN;
	}


	
	/*
		获取房间所有用户
	*/
	protected function getGamerInfo($room_id,$account_id=-1)
	{
		$result = array();
		
		$Redis_Model = Redis_Model::getModelObject();
		$MMYSQL = $this->initMysql();
		
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		//房间玩家集合
		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		$banker_mode = $this->queryBankerMode($room_id);
		
		//获取房间所有用户
		$sset_array['key'] = $RoomSequence_Key;
		$sset_array['WITHSCORES'] = "WITHSCORES";
		$gamer_query = $Redis_Model->getSortedSetLimitByAry($sset_array);
		if(Redis_CONST::DATA_NONEXISTENT !== $gamer_query)
		{
			foreach($gamer_query as $gamer_id=>$serial_num)
			{
				//获取玩家信息
				$account_where = 'account_id="'.$gamer_id.'"';
				$account_sql = 'select nickname,headimgurl from '.WX_Account.' where '.$account_where;
				$account_query = $MMYSQL->query($account_sql);
				if(!is_array($account_query) || count($account_query) == 0 )
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['serial_num'] = $serial_num;
				$info['account_id'] = $gamer_id;
				$info['nickname'] = $account_query[0]['nickname'];
				$info['headimgurl'] = $account_query[0]['headimgurl'];
				
				
				//获取玩家当前积分
				$rScore_score = $this->queryAccountScore($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rScore_score)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) score not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_score'] = $rScore_score;
				
				//获取玩家当前状态
				$rStatus = $this->queryAccountStatus($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rStatus)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) status not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_status'] = $rStatus;
				$info['online_status'] = $this->queryOnlineStatus($room_id, $gamer_id);
				$info['ticket_checked'] = $this->queryTicketChecked($room_id, $gamer_id);

				//是否庄家
				$is_banker = G_CONST::IS_FALSE;
				$banker_id = $this->queryBanker($room_id);
				if($banker_id == $gamer_id)
				{
					$is_banker = G_CONST::IS_TRUE;
				}
				$info['is_banker'] = $is_banker;

				$card_info = array();
				$card_type = 0;
				$combo_array = array();
				$combo_point = 0;
				if($rStatus == Game::AccountStatus_Show || $rStatus == Game::AccountStatus_Notshow){	//已经看过牌的
					$card_info = $this->queryCardInfo($room_id, $gamer_id);
					$cards_result = $this->caculateCardValue($room_id, $gamer_id,$card_info);
					$combo_array = $cards_result['combo_array'];
					$combo_point = $cards_result['combo_point'];
					$card_type = $cards_result['card_type'];
				}

				$info['cards'] = $card_info;
				$info['card_type'] = $card_type;
				$info['combo_array'] = $combo_array;
				$info['combo_point'] = $combo_point;
				$info['multiples'] = $this->queryPlayerMultiples($room_id, $gamer_id);

				$info['banker_multiples'] = "";
				if($banker_mode == Game::BankerMode_SeenGrab)
				{
					$banker_mult = $this->queryBankerMultiples($room_id);
					if($banker_mult != false)
					{
						$info['banker_multiples'] = $banker_mult;
					}
					
				}
				
				if($account_id == $gamer_id)
				{
					return $info;
				}
				
				$result[] = $info;
			}
		}
		
		return $result;
	}


	/*
		进房之前的查询
	*/
	public function prepareJoinRoom($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(PrepareJoinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close,max_count from '.Room.' where '.$room_where;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row)
		{
			$this->writeLog("function(PrepareJoinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}else{
			$room_id = $room_row['room_id'];
			$room_max_count = $room_row['max_count'];
			if($room_row['is_close'])
			{
				$result['room_status'] = 4;
				return array("result"=>"0","operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}

		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);

		$alert_text = "";
		$user_count = 0;

		$room_data = $this->queryRoomData($room_id);
		$room_status = $room_data['stat'];
		$spend_ticket_count = $room_data['ticketcnt'];

		$room_ary['room_status'] = $room_status;

		//规则
		$room_ary['user_count'] = $user_count;
		$room_ary['alert_text'] = $alert_text;
		//$room_ary['room_status'] = $this->queryRoomStatus($room_id);

		$room_rule = $this->queryRoomRule($room_id,$room_data); 
		$room_ary['ticket_type'] = $room_rule['ticket_type'];
		$room_ary['score_type'] = $room_rule['score_type'];
		$room_ary['rule_type'] = $room_rule['rule_type'];
		$room_ary['banker_mode'] = $room_rule['banker_mode'];
		$room_ary['banker_score_type'] = $room_rule['banker_score_type'];
		$room_ary['bet_type'] = $room_rule['bet_type'];
		$room_ary['is_cardjoker'] = 0;
		$room_ary['is_cardbao9'] = 0;
		if($room_rule['carddi'] > 1 || $room_rule['cardlei'] > 1 || $room_rule['cardtian'] > 1)
		{
			$room_ary['is_cardjoker'] = 1;
		}
		if($room_rule['cardbao9'] > 1)
		{
			$room_ary['is_cardbao9'] = 1;
		}
        $room_ary['creator_id'] = $room_data[Redis_CONST::Room_Field_Creator];
		//获取维护公告
		$alert_type = -1;
		$alert_text = "";
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
			$room_ary['alert_type'] = $alert_type;
			return array("result"=>"1","operation"=>$operation,"data"=>$room_ary,"result_message"=>$alert_text); 
		}

		if(Game::PaymentType_AA == Config::Ticket_Mode)
		{
			//$spend_ticket_count = $this->queryTicketCount($room_id);
			$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();

			if($my_ticket_count >= $spend_ticket_count || $this->queryTicketChecked($room_id, $account_id) >= 1){
				
			} else {
				$this->writeLog("[$room_id] ($account_id) 牌券不足");
				// $result['alert_type'] = 1;	//1房卡不足
				$room_ary['alert_type'] = 1;
				return array("result"=>"1","operation"=>$operation,"data"=>$room_ary,"result_message"=>"房卡不足"); 
			}
		}


		//房间人数
		$room_users = array();
		$is_member = false;
		//获取房间所有用户
		$sset_array['key'] = $RoomSequence_Key;
		$gamer_query = $Redis_Model->getSortedSetLimitByAry($sset_array);
		if(Redis_CONST::DATA_NONEXISTENT !== $gamer_query)
		{
			foreach($gamer_query as $gamer_id)
			{
				//获取玩家信息
				$account_where = 'account_id="'.$gamer_id.'"';
				$account_sql = 'select account_id,nickname from '.WX_Account.' where '.$account_where;
				$row = $MMYSQL->row($account_sql);
				if($row){
					$room_users[] = $row['nickname'];
					$user_count++;
					if($row['account_id'] == $account_id){
						$is_member = true;
					}
				} 
			}
		}

		if($user_count == 0 || $is_member){
			$alert_text = "";
		} else {
			if($user_count >= $room_max_count){
				$this->writeLog("[$room_id] ($account_id)  PrepareJoinRoom 人数已满");
				$room_ary['alert_type'] = 2;
				return array("result"=>"1","operation"=>$operation,"data"=>$room_ary,"result_message"=>"房间人数已满");  
			} 

			$user_str = implode("、", $room_users);
			$alert_text = "房间中有".$user_str."，是否加入？";
		}

		$room_ary['user_count'] = $user_count;
		$room_ary['alert_text'] = $alert_text;

		return array("result"=>"0","operation"=>$operation,"data"=>$room_ary,"result_message"=>"进房询问");  

		return OPT_CONST::NO_RETURN;
	}
	
	
	/*
		准备操作
	*/
	public function readyStart($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(readyStart):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		
		//获取玩家当前状态，是否未准备
		$rStatus = $this->queryAccountStatus($room_id, $account_id);
		if(Redis_CONST::DATA_NONEXISTENT === $rStatus || !in_array($rStatus, [Game::AccountStatus_Initial, Game::AccountStatus_Notready])  )
		{
			//广播用户状态改变
			$this->updateAccountStatus($room_id, $account_id, $rStatus);
			return OPT_CONST::NO_RETURN;
		}
		
		
		//更新用户状态
		$rStatus = Game::AccountStatus_Ready;
		$this->updateAccountStatus($room_id, $account_id, $rStatus);

		$this->startGame($room_id);
		
		return OPT_CONST::NO_RETURN;
	}
	
	/*
		历史积分榜
	*/
	public function historyScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];
		
		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}

		$MMYSQL = $this->initMysql();

		if(isset($data['room_number']))
		{
			$room_number = $data['room_number'];
			//判断房间申请记录是否存在
			$room_where = 'room_number="'.$room_number.'"';
			$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
			$room_query = $MMYSQL->query($room_sql);
			if(!is_array($room_query) || count($room_query) == 0 )
			{
				$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
			}else{
				$room_id = $room_query[0]['room_id'];
			}
		}
		else
		{
			if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
			{
				$this->logMessage('error', "function(historyScoreboard):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
				return $this->_missingPrameterArr($operation,"room_id");
			}
			$room_id = $data['room_id'];
		}
		
		$scoreboards = array();

		$sql = 'select * from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 10';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(historyScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__);
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				
				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score);
					}
					$scoreboards[] = array('time'=>$create_time, 'scoreboard'=>$name_board);
				}
			}
		}
		
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}

	/*
		最后一局积分榜
	*/
	public function lastScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(lastScoreboard):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}

		
		$room_number = $data['room_number'];
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}else{
			$room_id = $room_query[0]['room_id'];
		}

		$scoreboards = new stdClass();
		$sql = 'select * from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 1';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(lastScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__); 
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				$game_num = $row['game_num'];
				if($game_num <= 0)
				{
					$game_num = Config::GameNumber_Each;
				}

				$total_num = "";
				$rule_text = $row['rule_text'];
				$rule_text_array = explode('局/',$rule_text); 
				if(is_array($rule_text_array) && count($rule_text_array) > 0)
				{
					$total_num = $rule_text_array[0];
				}

				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
					}
					$scoreboards = array('time'=>$create_time, 'scoreboard'=>$name_board,'game_num'=>$game_num,'total_num'=>$total_num);
				}
			}
		}
		
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}


	/*
		上传经纬度信息
	*/
	public function uploadGeo($arrData)
	{
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
		{
			$this->logMessage('error', "function(uploadGeo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		if(!isset($data['longitude']) || !isset($data['latitude']) )
		{
			$this->logMessage('error', "function(uploadGeo):lack of longitude or latitude"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"longitude/latitude");
		}
		
		$room_id = $data['room_id'];
		$longitude = $data['longitude'];
		$latitude = $data['latitude'];

		$this->updateAccountGeo($room_id, $account_id, $longitude, $latitude);
		
		$msg_arr = array("result"=>0,"operation"=>"AccountGeo","data"=>array(
			'account_id'=>$account_id,
			'longitude'=>$longitude,
			'latitude'=>$latitude,
			),"result_message"=>"地理位置");

		$this->pushMessageToGroup($room_id, $msg_arr);
	}




	//{"operation":"TestDouble","account_id":"8","data":{"room_id":"8"}}
	// public function testDouble($arrData)
	// {
	// 	$timestamp = time();
	// 	$result = array();
	// 	$return = array();
		
	// 	$data 			= $arrData['data'];
	// 	$operation 		= $arrData['operation'];
	// 	$account_id 	= $arrData['account_id'];
	// 	$client_id 		= $arrData['client_id'];
		
	// 	if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
	// 	{
	// 		$this->logMessage('error', "function(testDouble):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
	// 		return $this->_missingPrameterArr($operation,"room_id");
	// 	}

	// 	$room_id = $data['room_id'];

	// 	$currentGamer_test = $this->getGamerInfo($room_id,$account_id);
	// 	$currentGamer_test['serial_num'] = 6;
	// 	$currentGamer_returnTest = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer_test,"result_message"=>"某玩家状态");

	// 	$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
	// 	$room_aid = strtr(Game::RoomUser_UID, $replyArr);

	// 	$this->pushMessageToAccount($room_aid, $currentGamer_returnTest);

	// 	return OPT_CONST::NO_RETURN;
	// }

    public function closeRoom($arrData)
    {
        $operation = $arrData['operation'];
        $data = $arrData['data'];
        $account_id = $arrData['account_id'];
        $room_number = $data['room_number'];



        // $current_timer_id = $this->queryTimerId($room_id);
        // if($current_timer_id == $timer_id){
        // 	$this->updateTimer($room_id, -1);
        // } else {
        // 	//timer对不上，返回
        // 	$this->writeLog("function(clearRoomPassive):timer对不上($current_timer_id != $timer_id)"." in file".__FILE__." on Line ".__LINE__);
        // 	return false;
        // }

        //判断是否全部人离线
        //$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
        //if(count($clients_of_groupid) > 0){
        //    $this->writeLog("function(clearRoomPassive):房间($room_id)有人不清理");
        //    return false;
        //}

        $MMYSQL = $this->initMysql();

        $room_where = 'room_number='.$room_number.' and is_close =0';
        $room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
        $room_query = $MMYSQL->query($room_sql);
        if(!is_array($room_query) || count($room_query) == 0 )
        {
            $this->writeLog("function(closeRoomManager):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        }else{
            $room_id = $room_query[0]['room_id'];
        }

        if ($room_query[0]['account_id'] != $account_id){
            $this->writeLog("function(closeRoomManager):room($room_number) no auth"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"不是管理员，不能关闭房间");
        }

        $this->writeLog("[$room_id] 触发群主清房间");

        $Redis_Model = Redis_Model::getModelObject();
        $replyArr = array("[roomid]"=>$room_id);
        $Room_Key = strtr(Redis_Const::Room_Key, $replyArr);

        $room_data = $this->queryRoomData($room_id);
        $game_num = $room_data['gnum'];
        $start_time = $room_data[Redis_CONST::Room_Field_StartTime];
        //$round = $room_data[Redis_Const::Room_Field_GameRound];
        $creator = $room_data[Redis_Const::Room_Field_Creator];
        $banker_mode = $room_data[Redis_Const::Room_Field_BankerMode];
        $banker_score = $room_data['bankerscore'];

        $pay_type = $this->queryPayType($room_id);
        if(Game::PaymentType_Creator == $pay_type && $game_num==0 && $creator>0)	//退换给房主
        {
            $spend_ticket_count = $this->queryTicketCount($room_id);
            $this->balanceTicket($room_id, $creator, - $spend_ticket_count);
            $this->writeLog("[$room_id] ($creator)退还票券：".$spend_ticket_count);
        }

        //保存积分榜
        if($game_num > 0){

            $round = $Redis_Model->hincrbyField($Room_Key, Redis_Const::Room_Field_GameRound, 1);

            $game_info['room_id'] = $room_id;
            $game_info['game_type'] = Game::Game_Type;
            $game_info['dealer_num'] = Config::Dealer_Num;
            $game_info['round'] = $round-1;

            $this->writeLog("[$room_id] 第".($round-1)."轮 结束!");

            $MMYSQL = $this->initMysql();

            $banker_id = $this->queryBanker($room_id);
            //$banker_score = $this->queryBankerScore($room_id);

            //获取积分榜
            $RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
            $scoreboard = $Redis_Model->hgetallField($RoomScore_Key);
            $board_json_str = "";
            $ticket_checked_user = $this->queryTicketCheckedUser($room_id);

            foreach ($scoreboard as $key => $value) {
                if(!in_array($key, $ticket_checked_user)){
                    //未扣房卡的用户不显示在积分榜上
                    unset($scoreboard[$key]);
                }
            }
            $save_scoreboard = $scoreboard;

            foreach ($scoreboard as $account_id => $score) {
                $account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
                $name = $MMYSQL->single($account_sql);
                if($banker_mode == Game::BankerMode_FixedBanker && $banker_id == $account_id)
                {
                    $score -= $banker_score;
                    $save_scoreboard[$account_id] = $score;
                }
                $name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
            }
            $balance_scoreboard = array('time'=>time(), 'scoreboard'=>$name_board,'game_num'=>$game_num);


            $board_json_str = json_encode($save_scoreboard);
            $balance_board_json_str = json_encode($balance_scoreboard['scoreboard']);

            //规则文本
            $rule_text = $this->formatRuleText($room_id,$room_data);

            $board_array['start_time'] = $start_time;
            $board_array['create_time'] = time();
            $board_array['is_delete'] = G_CONST::IS_FALSE;
            $board_array['game_type'] = Game::Game_Type;
            $board_array['room_id'] = $room_id;
            $board_array['round'] = $round-1;
            $board_array['game_num'] = $game_num;
            $board_array['board'] = $board_json_str;
            $board_array['balance_board'] = $balance_board_json_str;
            $board_array['rule_text'] = $rule_text;
            $board_id = $MMYSQL->insertReturnID(Room_Scoreboard,$board_array);

            //保存用户积分
            $game_info['score_board'] = $save_scoreboard;
            $this->saveAccountGameScore($game_info);
        }

//        $scoreboard = $this->getScoreBoard($room_id);
//        $this->pushMessageToGroup($room_id,$scoreboard);
        Gateway::closeCurrentClient();
        $client_list = Gateway::getClientInfoByGroup($room_id);
        foreach ($client_list as $client_id=>$item) {
            Gateway::closeClient($client_id);
        }
        //清理房间
        $this->initRoomData($room_id);

        return true;
    }
	
}